<?php

class RusslavBank {

	private $uri = 'https://contactws.russlavbank.com/trans/wsTrans.exe/soap/ITransmitter';
	private static $_instance;
	private $client = 0;
	private $version = 0;
	private $timeOut = 600;
	private $resultInArray;
	public $folder;
	private $caminho;
	private $file;
	private $sendPoint = 'ZRRG'; //antigo TZCM  //novo TZCL
	private $point_code = 'POINT_CODE="ZRRG"';
	private $point_id = 'POINT_ID="84725"';
	private $int_soft = 'INT_SOFT_ID="E69D4ABF-9937-4870-B985-BD66233471B3"';
	private $correspondentId = 'CorrespondentID="84725"';
	private $user_id = 'USER_ID="14957"';

	public function call($request) {
		$signature = $this->SignRequest($request);
		$request = base64_encode($request);
		$signature = base64_encode($signature);
		$inXML = '<?xml version="1.0" encoding="UTF-8"?>
          <CDTRN Version="1" ' . $this->correspondentId . ' Code="BASE64" Lang="en" Stamp="' . date('c') . '">
          <DATA Pack="NONE" Encryption="PLAIN">' . $request . '</DATA>
          <SIGNATURES>
          <SIGNATURE ALGO="RSA">' . $signature . '</SIGNATURE>
          </SIGNATURES>
          </CDTRN>';
		$MethodParams = array('inXML' => $inXML);
		//echo 'vai fazer o call'; die;
		$result = $this->client->call("Transmit", $MethodParams, 'urn:TransmitterIntf-ITransmitter', 'urn:TransmitterIntf-ITransmitter#Transmit');
		if ($this->client->error_str) {
			echo $this->client->error_str;
			echo '<script charset="utf-8" type="text/javascript">alert("Serviço RusslavBank Indisponível\n Taxa 3€ será assumida");</script>';
			die;
		}
		$result = $this->xml_getparse($result['outXML']);
		$result = base64_decode($result['CDTRN']['DATA']);
		$this->testa($result);
		return $result;
	}

	private function SignRequest($data) {
		$request = $this->caminho . 'request.xml';
		$signature = $this->caminho . 'request.der';
		$publicKey = $this->caminho . 'public.key';
		$privateKey = $this->caminho . 'private.key';
		//$program='C:\cygwin\bin\openssl.exe';
		$program='openssl';
		$result = file_put_contents($request, $data, LOCK_EX);
		if ($result === FALSE) {echo 'erro ao escrever o request';}
		$command = "$program smime -sign -nocerts -signer $publicKey -inkey $privateKey -keyform PEM -CAfile $publicKey -in $request -out $signature -binary -outform DER";
		$result=system($command);
		$signature = file_get_contents($signature);
		return $signature;
	}

	private function getChanges($version) {
		$request = '
                    <REQUEST DOC_ID=""
					SERVICE_ID=""
          			LANG="EN"
          			ACTION="GET_CHANGES"
          			OBJECT_CLASS="TAbonentObject"
          			' . $this->point_id . '
          			' . $this->user_id . '
          			' . $this->int_soft . '
          			VERSION="' . $version . '"
          			TYPE_VERSION="I"
          			PACK="ZLIB" />
          			';
		//echo $request;
		//die;
		$xml = $this->call($request);
		return $xml;
	}

	public function getFullDb() {
		//echo 'getFullDb'; die;
		return $this->getChanges(0);
	}

	public function getUpdatesForDb($version) {
		return $this->getChanges($version);
	}


	public function escreveXML($result) {
		$resultarray = $this->objectsIntoArray(simplexml_load_string($result));
		$this->version = $resultarray['@attributes']['VERSION'];
		$this->folder = $this->folder . '/' . $this->version;
		$this->file = $this->folder . '/' . $this->version . '.xml';
		if (is_dir($this->folder) || mkdir($this->folder, 0777, true)) {
			$result = file_put_contents($this->file, $result, LOCK_EX);
			if ($result > 0) {
				return true;
			} else {
				return false;
			}
		} else {
			echo 'erro ao criar a directoria:' . $this->folder;
			return false;
		}
	}

	public function setFolder($folder) {
		$this->folder = $folder;
	}

	public function getFolder() {
		return $this->folder;
	}

	public static function getInstance() {
		if (!(self::$_instance instanceof self)) {
			self::$_instance = new self();
		}
		return self::$_instance;
	}

	final private function __construct() {
		$this->caminho = $_SERVER['DOCUMENT_ROOT'] . '/../../common/russlavbank/';
		$this->folder = $this->caminho.'version';
		//$this->dbxml=$this->caminho . 'dbxml.xml';

		$path=$_SERVER['DOCUMENT_ROOT'] . '/../../' . '/etc/lib/nusoap-0.9.5/lib/';
		set_include_path(get_include_path() . PATH_SEPARATOR . $path);
		require_once('nusoap.php');
		$this->client = new nusoap_client($this->uri); //linux
		$this->client->timeout = $this->timeOut;
		$this->client->response_timeout = $this->timeOut;
		$this->client->CURLOPT_CONNECTIONTIMEOUT = $this->timeOut;
	}

	final private function __clone() {

	}

	function __destruct() {

	}

	public function getVersion() {
		return $this->version;
	}

	public function setVersion($version) {
		$this->version = $version;
	}

	public function mostraResultado($s) {
		$s = str_replace('&', '&amp;', $s);
		$s = str_replace("'", '&apos;', $s);
		$s = str_replace('"', '&quot;', $s);
		$s = str_replace('<', '&lt;', $s);
		$s = str_replace('>', '&gt;', $s);
		return $s;
	}

	private function converte($s) {
		$s = str_replace('&amp;', '&', $s);
		$s = str_replace('&apos;', "'", $s);
		$s = str_replace('&quot;', '"', $s);
		$s = str_replace('&lt;', '<', $s);
		$s = str_replace('&gt;', '>', $s);
		return $s;
	}

	private function GetPrivateKey($private_key_file, $pass) {
		$private_key = FALSE;
		$private_key = openssl_pkey_get_private(array("file://$private_key_file", $pass));
		if ($private_key === FALSE) {
			echo openssl_error_string();
			die;
		} else {
			return $private_key;
		}
	}

	public function calcFee($valor, $bank) {
		$moedaDestino = 'EUR';
		return $this->call('
            <REQUEST
            LANG="EN"
            SERVICE_ID=""
            OBJECT_CLASS="TMoneyOrderObject"
            ' . $this->point_id . '
            ' . $this->user_id . '
            ACTION="CalcFee"
            TRANSACTION_AMOUNT="' . $valor . '"
            TRANSACTION_CUR="EUR"
            ENTER_CUR="' . $moedaDestino . '"
            ENTER_AMOUNT="' . $valor . '"
            TO_BANK="' . $bank . '"
            />');
	}

	public function getReference($idDaRemessa) {
		$result = $this->get($idDaRemessa);
		$result = simplexml_load_string($result);
		return $result->trnReference;
	}

	//Getting Information on the Money Order or Payment - TMoneyOrderObject.Get
	public function get($idDaRemessa) {
		return $this->call('
            <REQUEST
            LANG="EN"
            SERVICE_ID=""
            OBJECT_CLASS="TMoneyOrderObject"
            ' . $this->point_id . '
            ' . $this->user_id . '
            ACTION="Get"
            DOC_ID="' . $idDaRemessa . '"
            INOUT="O" />');
	}

	//Checking for the money order/payment attributes
	public function check($pickupPoint) {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="Check"
                    ' . $this->point_id . '
                    ' . $this->point_code . '
                    ' . $this->user_id . '
                    ' . $this->int_soft . '
                    SERVER_IP="196.168.1.52"
                    CLIENT_IP="196.168.1.52">
                        <trnDate>20100630</trnDate>
                        <trnCurrency>USD</trnCurrency>
                        <trnAmount>500.00</trnAmount>
                        <trnSendPoint>' . $this->sendPoint . '</trnSendPoint>
                        <trnPickupPoint>' . $pickupPoint . '</trnPickupPoint>
                        <trnService>2</trnService>
                        <trnAdditionalInfo>qqq</trnAdditionalInfo>
                        <sResident>0</sResident>
                        <sName>PAUL</sName>
                        <sLastName>SMITH</sLastName>
                        <sBirthday>19900101</sBirthday>
                        <sCountry>BY</sCountry>
                        <sCity>MOSCOW</sCity>
                        <sAddress>MINSK</sAddress>
                        <sIDtype>PASSPORT</sIDtype>
                        <sIDnumber>123456789</sIDnumber>
                        <sIDdate>20000113</sIDdate>
                        <sIDwhom>STATE AUTHORITY</sIDwhom>
                        <bName>JOHN</bName>
                        <bLastName>SMITH</bLastName>
                        <bIDexpireDate />
                        <bResident />
                </REQUEST>');
	}

	public function returnOutgoing($idRemessa) {
		return $this->call('
            <REQUEST
            DOC_ID="' . $idRemessa . '"
            OBJECT_CLASS="TMoneyOrderObject"
            ACTION="ReturnOutgoing"
            ' . $this->int_soft . '
            ' . $this->point_code . '
            ' . $this->user_id . '
            LANG="EN" />
            ');
	}

	//Creating and Paying a New Money Order
	public function newAndSendOutgoing($pickupPoint) {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="NewAndSendOutgoing"
                    ' . $this->point_id . '
                    ' . $this->point_code . '
                    ' . $this->user_id . '
                    ' . $this->int_soft . '
                    SERVER_IP="196.168.1.52"
                    CLIENT_IP="196.168.1.52">
                        <trnDate>20100630</trnDate>
                        <trnCurrency>RUR</trnCurrency>
                        <trnAmount>100.00</trnAmount>
                        <trnSendPoint>' . $this->sendPoint . '</trnSendPoint>
                        <trnPickupPoint>' . $pickupPoint . '</trnPickupPoint>
                        <trnService>2</trnService>
                        <trnAdditionalInfo>qqq</trnAdditionalInfo>
                        <sResident>0</sResident>
                        <sName>PAUL</sName>
                        <sLastName>SMITH</sLastName>
                        <sBirthday>19900101</sBirthday>
                        <sCountry>BY</sCountry>
                        <sCity>MOSCOW</sCity>
                        <sAddress>MINSK</sAddress>
                        <sIDtype>PASSPORT</sIDtype>
                        <sIDnumber>123456789</sIDnumber>
                        <sIDdate>20000113</sIDdate>
                        <sIDwhom>STATE AUTHORITY</sIDwhom>
                        <bName>JOHN</bName>
                        <bLastName>SMITH</bLastName>
                        <bIDexpireDate />
                        <bResident />
                </REQUEST>');
	}

	//Deleting a Money Order or Payment - TMoneyOrderObject.DeleteOutgoing
	public function deleteOutGoing($idDaRemessa) {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="DeleteOutgoing"
                    ' . $this->point_id . '
                    ' . $this->user_id . '
                    DOC_ID="' . $idDaRemessa . '"/>'
                    );
	}

	//Changing the Money Order Attributes - TMoneyOrderObject.ChangeOutgoing
	public function changeOutGoing($idDaRemessa, $pickupPoint) {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="ChangeOutgoing"
                    ' . $this->point_id . '
                    ' . $this->point_code . '
                    ' . $this->user_id . '
                    DOC_ID="' . $idDaRemessa . '"
                    ' . $this->int_soft . '
                    SERVER_IP="196.168.1.52"
                    CLIENT_IP="196.168.1.52">
                        <trnDate>20110113</trnDate>
                        <trnCurrency>EUR</trnCurrency>
                        <trnAmount>1.00</trnAmount>
                        <trnSendPoint>' . $this->sendPoint . '</trnSendPoint>
                        <trnPickupPoint>' . $pickupPoint . '</trnPickupPoint>
                        <trnService>2</trnService>
                        <trnAdditionalInfo>qqq</trnAdditionalInfo>
                        <sResident>0</sResident>
                        <sName>PP</sName>
                        <sLastName>PP</sLastName>
                        <sBirthday>20110113</sBirthday>
                        <sCountry>p</sCountry>
                        <sCity>p</sCity>
                        <sAddress>p</sAddress>
                        <sIDtype>p</sIDtype>
                        <sIDnumber>123</sIDnumber>
                        <sIDdate>20000113</sIDdate>
                        <sIDwhom>estado</sIDwhom>
                        <bName>Paulo</bName>
                        <bLastName>Abrantes</bLastName>
                        <bIDexpireDate />
                        <bResident />
                </REQUEST>');
	}

	//Request for Cancellation - TMoneyOrderObject.ReqForCancel
	public function requestForCancellation($idDaRemessa) {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="ReqForCancel"
                    ' . $this->point_id . '
                    ' . $this->point_code . '
                    ' . $this->user_id . '
                    DOC_ID="' . $idDaRemessa . '"
                    />');
	}

	// Getting a List of Sent Money Orders and/or Payments -TMoneyOrderObject.OutgoingSent

	public function outGoingSent() {
		$result = $this->call(
                        '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="OutgoingSent"
                    ' . $this->point_id . '
                    ' . $this->point_code . '
                    ' . $this->user_id . '>
                    <PARAMS DT_FILE="20101124"/>
                    </REQUEST>');
		return $this->converte($result);
	}

	//Getting a List of Remote Money Orders and/or Payments -TMoneyOrderObject.OutgoingDeleted
	public function outGoingDeleted() {
		$result = $this->call(
                        '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="OutgoingDeleted"
                    ' . $this->point_id . '
                    ' . $this->user_id . '>
                    </REQUEST>');
		return $this->converte($result);
	}

	//Getting a List of Draft Money Orders and/or Payments - TMoneyOrderObject.OutgoingDraft
	public function outGoingDraft() {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="OutgoingDraft"
                    ' . $this->point_id . '
                    ' . $this->user_id . '>
                    </REQUEST>');
	}

	//Getting a List of Money Orders and/or Payments Waiting to Be Paid - TMoneyOrderObject.OutgoingWaitingForPay
	public function outGoingWaitingForPay() {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="OutgoingWaitingForPay"
                    ' . $this->point_id . '
                    ' . $this->user_id . '>
                </REQUEST>
                    ');
	}

	//Getting a List of Sent and Cancelled Money Orders -TMoneyOrderObject.OutgoingCancelled
	public function outGoingCancelled() {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="OutgoingCancelled"
                    ' . $this->point_id . '
                    ' . $this->user_id . '>
                    <PARAMS DT_FILE="20101124"/>
                    </REQUEST>');
	}

	//Getting a List of Money Orders Sent and Requested for Cancellation -TMoneyOrderObject.OutgoingRequested
	public function outGoingRequested() {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="OutgoingRequested"
                    ' . $this->point_id . '
                    ' . $this->user_id . '>
                    </REQUEST>');
	}

	//Getting a List of Money Orders Ready for Return   -TMoneyOrderObject.OutgoingToReturn
	public function outGoingToReturn() {
		$result = $this->call(
                        '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="OutgoingToReturn"
                    ' . $this->point_id . '
                    ' . $this->user_id . '>
                    </REQUEST>');
		return $this->converte($result);
	}

	//Getting a List of Money Orders Waiting to Be Returned to the Sender -TMoneyOrderObject.OutgoingWaitingToReturn
	public function outGoingWaitingToReturn() {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="OutgoingWaitingToReturn"
                    ' . $this->point_id . '
                    ' . $this->user_id . '>
                    </REQUEST>');
	}

	//Getting a List of Money Orders Returned to the Sender at a Point - TMoneyOrderObject.OutgoingReturned
	public function outGoingReturned() {
		$result = $this->call(
                        '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="OutgoingReturned"
                    ' . $this->point_id . '
                    ' . $this->user_id . '>
                    <PARAMS DT_FILE="20101124"/>
                    </REQUEST>');
		return $this->converte($result);
	}

	//Getting a List of Money Orders Returned to the Sender in the Branch -TMoneyOrderObject.OutgoingReturnedlnBranch
	public function outGoingReturnedInBranch() {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="OutgoingReturnedInBranch"
                    ' . $this->point_id . '
                    ' . $this->user_id . '>
                    <PARAMS DT_FILE="20101124"/>
                    </REQUEST>');
	}

	//Getting a List of Money Orders Returned to the Sender in the Bank -TMoneyOrderObject.OutgoingReturnedInBank
	public function outGoingReturnedInBank() {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="OutgoingReturnedInBank"
                    ' . $this->point_id . '
                    ' . $this->user_id . '>
                    <PARAMS DT_FILE="20101124"/>
                    </REQUEST>');
	}

	//Getting a List of Money Orders Returned to the Sender by a Specified User - TMoneyOrderObject.OutgoingReturnedByUser
	public function outGoingReturnedByUser() {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="OutgoingReturnedByUser"
                    ' . $this->point_id . '
                    ' . $this->user_id . '>
                    <PARAMS DT_FILE="20101124"/>
                    </REQUEST>');
	}

	//Getting a List of Money Orders Ready to Be Paid to the Recipient at a Specified Point - TMoneyOrderObject.IncomingReadyToPay
	public function incomingReadyToPay() {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="IncomingReadyToPay"
                    ' . $this->point_id . '
                    ' . $this->user_id . '>
                    <PARAMS DT_FILE="20101124"/>
                    </REQUEST>');
	}

	//Getting a List of Money Orders Waiting to Be Paid to the Recipient -TMoneyOrderObject.IncomingWaitingToPay
	public function incomingWaitingToPay() {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="IncomingWaitingToPay"
                    ' . $this->point_id . '
                    ' . $this->user_id . '>
                    <PARAMS DT_FILE="20101124"/>
                    </REQUEST>');
	}

	//Getting a List of Money Orders Paid at a Point -TMoneyOrderObject.IncomingPaid
	public function incomingPaid() {
		$result = $this->call(
                        '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="IncomingPaid"
                    ' . $this->point_id . '
                    ' . $this->user_id . '>
                    <PARAMS DT_FILE="20101124"/>
                    </REQUEST>');
		return $this->converte($result);
	}

	//Getting a List of Money Orders Paid in the Branch -TMoneyOrderObject.IncomingPaidInBranch
	public function incomingPaidInBranch() {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="IncomingPaidInBranch"
                    ' . $this->point_id . '
                    ' . $this->user_id . '>
                    <PARAMS DT_FILE="20101124"/>
                    </REQUEST>');
	}

	//Getting a List of Money Orders Paid in the Bank -TMoneyOrderObject.IncomingPaidInBank
	public function incomingPaidInBank() {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="IncomingPaidInBank"
                    ' . $this->point_id . '
                    ' . $this->user_id . '>
                    <PARAMS DT_FILE="20101124"/>
                    </REQUEST>');
	}

	//Getting a List of Money Orders Paid by a Specified User -TMoneyOrderObject.IncomingPaidByUser
	public function incomingPaidByUser() {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="IncomingPaidByUser"
                    ' . $this->point_id . '
                    ' . $this->user_id . '>
                    <PARAMS DT_FILE="20101124"/>
                    </REQUEST>');
	}

	public function toPayOutgoing($idDaRemessa) {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="ToPayOutgoing"
                    ' . $this->point_id . '
                    ' . $this->user_id . '
                    DOC_ID="' . $idDaRemessa . '"/>'
                    );
	}

	public function payOutGoing($idDaRemessa) {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="PayOutgoing"
                    ' . $this->point_id . '
                    ' . $this->user_id . '
                    DOC_ID="' . $idDaRemessa . '"/>'
                    );
	}

	//Getting Information on the Payer - TMoneyOrderObject.GetPayerInfo
	public function getPayerInfo() {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="GetPayerInfo"
                    ' . $this->point_id . '
                    ' . $this->user_id . '
                    sName="ABD"
                    sLastName="AL"
                    sSurName="HAMID"
                    sBirthday="19490428"
                    />'
                    );
	}

	public function getPayerTemplates() {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="GetPayerTemplates"
                    ' . $this->point_id . '
                    ' . $this->user_id . '
                    CLIENT_ID="1"
                    />'
                    );
	}

	public function toPayIncoming($numeroDoDocumento) {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="ToPayIncoming"
                    ' . $this->point_id . '
                    ' . $this->user_id . '
                    CLIENT_ID="1"
                    DOC_ID="' . $numeroDoDocumento . '"
                    >
                    </REQUEST>'
                    );
	}

	public function payIncoming($numeroDoDocumento) {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="PayIncoming"
                    ' . $this->point_id . '
                    ' . $this->user_id . '
                    DOC_ID="' . $numeroDoDocumento . '"
                    >
                    </REQUEST>'
                    );
	}

	public function getState($numeroDoDocumento) {
		return $this->call(
                '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="GetState"
                    ' . $this->point_id . '
                    ' . $this->user_id . '
                    DOC_ID="' . $numeroDoDocumento . '"
                    />'
                    );
	}

	public function testa($result) {
		if ($this->resultInArray['@attributes']['RE'] == 0) {
			return true;
		} else {
			$mensagem = $this->resultInArray['@attributes']['ERR_TEXT'];
			echo '<script charset="utf-8" type="text/javascript">alert("' . $mensagem . '");</scipt>';
			echo $mensagem;
			return false;
		}
	}

	public function getUltimaVersaoEscrita() {
		//echo $this->folder;
		$directoria = @opendir($this->folder);
		if($directoria==FALSE){
			mkdir($this->folder,0777);
			$directoria = opendir($this->folder);
		}
		//var_dump($directoria);die;
		while ($result = readdir($directoria)) {
			if (is_numeric($result)) {
				$this->version = $result;
			}
		}
		//var_dump($this->version);
		//die;
		return $this->version;
	}

	public function readXMLCodificado() {
		$this->version = $this->getUltimaVersaoEscrita();
		$filename = $this->folder . '/' . $this->version . '/' . $this->version . '.xml';
		//var_dump($filename);
		//die;
		$result = file_get_contents($filename);
		$result = simplexml_load_string($result);
		$result = $this->objectsIntoArray($result);
		$this->resultInArray = $result;
		reset($result);
		while (current($result) !== FALSE || empty($result)) {
			$tabela = key($result);
			if ($tabela === '@attributes') {
				next($result);
				$tabela = key($result);
			}
			$xmlDescompactado = iconv('windows-1251', 'utf-8', gzuncompress(base64_decode($result[key($result)])));
			$ficheiro = $this->folder . '/' . $this->version . '/' . $tabela . '.xml';
			//echo $ficheiro . '<br />';
			if (file_put_contents($ficheiro, $xmlDescompactado)) {

			} else {
				echo 'Não consigo escrever';
				return false;
			}
			next($result);
		}
		return true;
	}

	public function escreveNaBD() {
		global $db;
		global $__DBHOST, $__DBUSER, $__DBPASS, $__DBT;
		$db->connect($__DBHOST, $__DBUSER, $__DBPASS, $__DBT);
		$this->db=$db;
		//var_dump($db);die;
		$result = false;
		$this->version = $this->getUltimaVersaoEscrita();
		$this->folder = $this->folder .'/'. $this->version;
		//var_dump($this->folder);die;

		$sql = 'drop database if exists russlavbank;';
		$result = $db->query($sql);

		$sql = 'create database russlavbank character set utf8 collate utf8_unicode_ci;';
		$result = $db->query($sql);

		$sql = 'use russlavbank;';
		$result = $db->query($sql);

		$directoria = opendir($this->folder);
		if ($directoria) {
			$ficheiros = array();
			while ($ficheiro = readdir($directoria)) {

				if ($ficheiro == '..' || $ficheiro == '.' || $ficheiro == 'LOGO.xml' || $ficheiro == 'IC_CODES.xml' || $ficheiro == 'BAD_DOC.xml' || $ficheiro == $this->version . '.xml') {
					continue;
				}

				if ($this->leFicheiro($ficheiro)) {
					$result = true;
					continue;
				} else {
					$result = false;
					break;
				}
			}
			closedir($directoria);
		} else {
			echo 'Erro ao abrir a directoria';
		}
		return $result;
	}

	public function respostaOk($a) {
		if ($a['@attributes']['RE'] == 0) {
			return true;
		} else {
			return false;
		}
	}



	public function respostaValida($resposta) {
		return ($resposta['@attributes']['RE'] == 0);
	}

	private function leFicheiro($ficheiro) {
		global $db;
		//echo 'leFicheiro';
		//var_dump($db);die;
		$xmlUrl = $this->folder . DIRECTORY_SEPARATOR . $ficheiro;
		//echo $xmlUrl;

		$xmlStr = file_get_contents($xmlUrl);
		$xmlObj = simplexml_load_string($xmlStr);
		$arrXml = $this->objectsIntoArray($xmlObj);
		$campos = $arrXml['METADATA']['FIELDS']['FIELD'];

		//$db = Db::getInstance();
		$tabela = substr($ficheiro, 0, -4);
		$stringDeCampos = ' ';
		foreach ($campos as $campo) {
			$nome = $campo['@attributes']['attrname'];
			$tipo = $campo['@attributes']['fieldtype'];
			if ($nome == 'ID') {
				$tipo = 'int';
			} else {
				$tipo = 'varchar (255)';
			}
			$stringDeCampos = $stringDeCampos . $nome . ' ' . $tipo . ',';
		}
		echo '<br />';
		$stringDeCampos = substr($stringDeCampos, 0, -1);
		$sql = 'create table ' . $tabela . '(' . $stringDeCampos . ') engine=innodb charset=utf8 collate=utf8_unicode_ci ;';
		//var_dump($db);
		//die;
		$result = $db->query($sql);

		if ($result) {
			//echo $sql . '<br />';
		} else {
			echo 'ERROR: ' . $sql . '<br />';
			die;
		}
		$campos = $arrXml['ROWDATA']['ROW'];

		echo 'numero de linhas a inserir na tabela: ' . $tabela . ' ' . count($campos) . '<br />';
		$count = 0;
		foreach ($campos as $campo) {
			$stringDevalores = '';
			$stringDeNomes = '';
			$array = $campo['@attributes'];
			$tamanho = count($array);
			for ($i = 0; $i < $tamanho; $i++) {
				$key = key($array);
				$valor = $array[$key];
				next($array);
				$stringDeNomes = $stringDeNomes . $key . ',';
				$stringDevalores = $stringDevalores . $db->quote($valor) . ',';
			}
			$stringDevalores = substr($stringDevalores, 0, -1);
			$stringDeNomes = substr($stringDeNomes, 0, -1);
			$sql = 'insert into ' . $tabela . '(' . $stringDeNomes . ') values (' . $stringDevalores . ');';
			$result = $db->query($sql);
			$count++;
			if ($result == true) {
				continue;
			} else {
				//echo 'Erro ao inserir uma query: '.$sql.'<br />'.$result.'<br />';
				//die;
			}
		}
		echo 'numero de linhas inseridas: ' . $count;
		echo 'fim<br /><br />';
		//die;
		return true;
	}

	public function existeBanco($nomeDoBanco) {
		$db = Db::getInstance();
		$sql = "
            select bp_id
            from officeschema.hd_bancos
            where officeschema.hd_bancos.bp_Name like '$nomeDoBanco';";
		$result = $db->getall($sql);
		if (count($result) >= 1) {
			return true;
		} else {
			return false;
		}
	}

	private function limpaCaractes($string) {
		$string = str_replace(",", "", $string);
		$string = str_replace("'", "", $string);
		$string = str_replace('"', '', $string);
		$string = str_replace("(", '', $string);
		$string = str_replace(")", '', $string);
		return $string;
	}

	public function getBancos() {
		global $db;

		//ON DUPLICATE KEY UPDATE
		//original 623
		//tamanho 36393


		$sql = "
		select id,name,country
		from russlavBank.banks
		where ERASED=0
		and deleted=0
		and rec_curr like '%EUR%'
		and country !=620";
		$result = $db->getall($sql);

		echo count($result);
		$values = '';
		/*foreach($result as $banco){
			$values = $values . '(' .$banco->id.','.$banco->name . ',' . $banco->country . '),';
			}
			$values = substr($values, 0, -1);
			$sql = "
			insert into officeschema.hd_bancos (bp_idbanco,bp_Name,bp_Country)
			values $values;";
			return $db->query($sql);*/

		foreach($result as $banco){
			if ($banco->country == 0) {
				$banco->country = 643;
			}
			$sql = '
            insert into officeschema.hd_bancos (bp_idbanco,bp_Name,bp_Country)
            values (' .$db->quote($banco->id).','.$db->quote($banco->name). ',' .$db->quote($banco->country). ') on duplicate key update bp_idbanco='.$db->quote($banco->id).';';
			$db->query($sql);

		}
		return true;

		die;
		$sql = "select bp_name as nome from officeschema.hd_bancos;";
		$bancostuga = $db->getallsinglearray($sql);

		$a = $bancosrusslav;
		$b = $bancostuga;

		$c = array_unique(array_merge($a, $b));
		$c = array_diff($c, $b);

		$bancosAInserir = $c;
		$tamanho = count($c);
		echo 'tamanho'.$tamanho.'<br />';
		if ($tamanho == 0) {
			return true;
		}
		$sql = "select id,name,country from russlavBank.banks where ERASED=0 and deleted=0 and rec_curr like '%EUR%' and country !=620;";
		$bancoscompaises = $db->getall($sql);
		$bancos = array();
		$paises = array();
		$ids=array();

		foreach ($bancoscompaises as $bancocompais) {


			if (in_array($bancocompais->name, $bancosAInserir)) {

				array_push($bancos, $db->quote($bancocompais->name));
				//643 - Russian Federation
				if ($bancocompais->country == 0) {
					$bancocompais->country = 643;
				}
				array_push($paises, $bancocompais->country);
				array_push($ids, $bancocompais->id);
				/*if($bancocompais->country==276)
				 {
					//printArray($bancocompais);
					printArray($bancos);
					printArray($paises);
					printArray($ids);
					//die;
					break;
					}*/
			}
		}
		echo 'bancos'.count($bancos).'<br />';
		echo 'paises'.count($paises).'<br />';
		echo 'ids'.count($ids).'<br />';
		die;

		$sql = "
            insert into officeschema.hd_bancos
            (bp_idbanco,bp_Name,bp_Country)
            values $values;";

		echo $sql . '<br />';
		return true;
		die;
		return $db->query($sql);
	}

	public function actualizaPagadores() {
		return true;
		//verse está a ser utilizada...
		global $db;
		$sql = '
		delete from officeschema.hd_bancospagadores
		where hd_bancospagadores.bpp_corr=306;';
		if ($db->query($sql)) {
		} else {
			echo $sql;
			die;
		}
		//die;
		$sql = 'select bp_name as name  from officeschema.hd_bancos;';
		$bancos = $db->getall($sql);
		//printArray($bancos);

		foreach ($bancos as $banco) {
			//306
			$sql = "
            select id
            from russlavBank.banks
            where russlavBank.banks.NAME like ".$db->quote($banco->name)
			." and ERASED=0 and deleted=0;";
			//echo $sql;
			$result = $db->getall($sql);

			if (count($result) > 0) {
				$sql = "
				select bp_ID as id
            	from officeschema.hd_bancos
            	where hd_bancos.bp_name =" .$db->quote($banco->name).";";
				$result = $db->getall($sql);

				if (count($result) > 0) {
					$sql = '
					update officeschema.hd_bancos set bp_Flag=2 where bp_ID='.$db->quote($result[0]->id).';';
					//echo $sql . '<br />';
					$db->query($sql);

					$sql = '
					insert into  officeschema.hd_bancospagadores
					(bpp_idbanco,bpp_nombrebanco,bpp_corr,status)
					values ('. $db->quote($result[0]->id).','.$db->quote($banco->name).',306,5);';
					//echo $sql . '<br />';
					//printArray($result);
					//echo 'fim';
					//return true;


					$db->query($sql);
				} else {
					echo 'errro: ' . $sql . '<br />';die;
				}
			}
		}
		return true;
	}

	public function novaRessaEPagar() {
		$resposta = $this->NewAndSendOutgoing();
		$resposta = $this->objectsIntoArray(simplexml_load_string($resposta));
		$idDaRemessa = $resposta['@attributes']['ID'];
		$resposta = $this->getState($idDaRemessa);
		$resposta = $this->objectsIntoArray(simplexml_load_string($resposta));
		$estado = $resposta['@attributes']['STATE'];
		return $estado;
	}

	public function novaRemessa($tipoDeDocumentoDeIdentidicacaoDoBeneficiario, $numeroDoDocumentoDeIdentificacaoDoBeneficiario, $dataDeEmissaoDoDocumentoDeIdentificaocaoDoBeneficiario, $entidadeGeradoraDoDocumentoDeIdentificaocaoDoBeneficiario, $dataDeEnvio, $valor, $informacaoAdicional, $primeiroNome, $ultimoNome, $dataDeNascimento, $cidade, $pais, $endereco, $tipoDeDocumentoDeIdentidicacao, $numeroDoDocumentoDeIdentificacao, $dataDeEmissaoDoDocumentoDeIdentificaocao, $entidadeGeradoraDoDocumentoDeIdentificaocao, $primeiroNomeDoBeneficiario, $ultimoNomeDoBeneficiario, $pickupPoint) {
		echo "$tipoDeDocumentoDeIdentidicacaoDoBeneficiario, $numeroDoDocumentoDeIdentificacaoDoBeneficiario, $dataDeEmissaoDoDocumentoDeIdentificaocaoDoBeneficiario, $entidadeGeradoraDoDocumentoDeIdentificaocaoDoBeneficiario, $dataDeEnvio, $valor, $informacaoAdicional, $primeiroNome, $ultimoNome, $dataDeNascimento, $cidade, $pais, $endereco, $tipoDeDocumentoDeIdentidicacao, $numeroDoDocumentoDeIdentificacao, $dataDeEmissaoDoDocumentoDeIdentificaocao, $entidadeGeradoraDoDocumentoDeIdentificaocao, $primeiroNomeDoBeneficiario, $ultimoNomeDoBeneficiario, $pickupPoint";

		$resposta = $this->newOutGoing($tipoDeDocumentoDeIdentidicacaoDoBeneficiario, $numeroDoDocumentoDeIdentificacaoDoBeneficiario, $dataDeEmissaoDoDocumentoDeIdentificaocaoDoBeneficiario, $entidadeGeradoraDoDocumentoDeIdentificaocaoDoBeneficiario, $dataDeEnvio, $valor, $informacaoAdicional, $primeiroNome, $ultimoNome, $dataDeNascimento, $cidade, $pais, $endereco, $tipoDeDocumentoDeIdentidicacao, $numeroDoDocumentoDeIdentificacao, $dataDeEmissaoDoDocumentoDeIdentificaocao, $entidadeGeradoraDoDocumentoDeIdentificaocao, $primeiroNomeDoBeneficiario, $ultimoNomeDoBeneficiario, $pickupPoint);
		if ($this->erroRusslav) {
			return 0;
		}
		$resposta = $this->objectsIntoArray(simplexml_load_string($resposta));
		$id = $resposta['@attributes']['ID'];
		return $id;
	}

	//Creating a New Money Order or Payment
	//A remessa irá ficar no estado 100
	public function newOutGoing($tipoDeDocumentoDeIdentidicacaoDoBeneficiario, $numeroDoDocumentoDeIdentificacaoDoBeneficiario, $dataDeEmissaoDoDocumentoDeIdentificaocaoDoBeneficiario, $entidadeGeradoraDoDocumentoDeIdentificaocaoDoBeneficiario, $dataDeEnvio, $valor, $informacaoAdicional, $primeiroNome, $ultimoNome, $dataDeNascimento, $cidade, $pais, $endereco, $tipoDeDocumentoDeIdentidicacao, $numeroDoDocumentoDeIdentificacao, $dataDeEmissaoDoDocumentoDeIdentificaocao, $entidadeGeradoraDoDocumentoDeIdentificaocao, $primeiroNomeDoBeneficiario, $ultimoNomeDoBeneficiario, $pickupPoint) {
		$request = '<REQUEST
                    LANG="EN"
                    OBJECT_CLASS="TMoneyOrderObject"
                    ACTION="NewOutgoing"
                    ' . $this->point_id . '
                    ' . $this->point_code . '
                    ' . $this->user_id . '
                    ' . $this->int_soft . '
                    SERVER_IP="196.168.1.52"
                    CLIENT_IP="196.168.1.52">
                        <trnDate>' . $dataDeEnvio . '</trnDate>
                        <trnCurrency>EUR</trnCurrency>
                        <trnAmount>' . $valor . '</trnAmount>
                        <trnSendPoint>' . $this->sendPoint . '</trnSendPoint>
                        <trnPickupPoint>' . $pickupPoint . '</trnPickupPoint>
                        <trnService>2</trnService>
                        <trnAdditionalInfo>' . $informacaoAdicional . '</trnAdditionalInfo>
                        <sResident>0</sResident>
                        <sName>' . $primeiroNome . '</sName>
                        <sLastName>' . $ultimoNome . '</sLastName>
                        <sBirthday>' . $dataDeNascimento . '</sBirthday>
                        <sCountry>' . $pais . '</sCountry>
                        <sCity>' . $cidade . '</sCity>
                        <sAddress>' . $endereco . '</sAddress>
                        <sIDtype>' . $tipoDeDocumentoDeIdentidicacao . '</sIDtype>
                        <sIDnumber>' . $numeroDoDocumentoDeIdentificacao . '</sIDnumber>
                        <sIDdate>' . $dataDeEmissaoDoDocumentoDeIdentificaocao . '</sIDdate>
                        <sIDwhom>' . $entidadeGeradoraDoDocumentoDeIdentificaocao . '</sIDwhom>
                        <bName>' . $primeiroNomeDoBeneficiario . '</bName>
                        <bLastName>' . $ultimoNomeDoBeneficiario . '</bLastName>
                        <bPhone>129894654</bPhone>
                        <bIDtype>' . $tipoDeDocumentoDeIdentidicacaoDoBeneficiario . '</bIDtype>
                        <bIDnumber>' . $numeroDoDocumentoDeIdentificacaoDoBeneficiario . '</bIDnumber>
                        <bIDdate>' . $dataDeEmissaoDoDocumentoDeIdentificaocaoDoBeneficiario . '</bIDdate>
                        <bIDwhom>' . $entidadeGeradoraDoDocumentoDeIdentificaocaoDoBeneficiario . '</bIDwhom>
                        <bIDexpireDate />
                        <bResident />
                </REQUEST>';
		$result = $this->objectsIntoArray(simplexml_load_string($request));
		$result = $this->call($request);
		if ($this->erroRusslav) {
			return 0;
		}
		$request = $this->objectsIntoArray(simplexml_load_string($result));
		return $result;
	}

	public function inserirCambios() {
		global $db;
		$sql = "delete from officeschema.hd_cambiosdia
		where officeschema.hd_cambiosdia.htr_NombreCorresponsal='RUSSLAVBANK'
		or
		officeschema.hd_cambiosdia.htr_Corresponsal=306
		;";
		//echo $sql . '<br />';
		$db->query($sql);

		//643 - Russian Federation
		$sql = "
		select id,name_lat as nome
		from russlavbank.country
		where erased=0
		and rec_curr like '%EUR%'
		and id != 620
		;";
		$result = $db->getall($sql);

		foreach ($result as $pais) {
			if ($pais->id == 0) {
				if ($pais->nome == 'RUSSIAN FEDERATION') {
					$pais->id = 643;
				}
			}
			$sql = "
            insert into officeschema.hd_cambiosdia
            (htr_tarifa,htr_corresponsal,htr_nombrecorresponsal,htr_pais,htr_MCobro,htr_mpago,htr_NombreMPago,htr_monpagoiso)
            value
            (0,306,'RUSSLAVBANK',$pais->id,1,'EUR','EUR','EUR');";
			//echo $sql . '<br />';
			if ($db->query($sql)) {
				//echo 'ok<br />';
			} else {
				echo 'ko<br />';
				die;
			}
		}
		return true;
	}

	public function updateCidadesTuga() {
		global $db;

		$sql = "select city_lat as nome from russlavbank.bnk_city;";
		$cidadeRusslav = $db->getallsinglearray($sql);
		//printArray($cidadeRusslav);die;
		$sql = "select CiuCiudad as nome from officeschema.ciudades;";
		$cidadeTuga = $db->getallsinglearray($sql);

		$a = $cidadeRusslav;
		$b = $cidadeTuga;

		$c = array_unique(array_merge($a, $b));
		$c = array_diff($c, $b);

		$cidadesAInserir = $c;
		$tamanho = count($cidadesAInserir);
		if ($tamanho == 0) {
			return true;
		}
		$sql = "select city_lat as nome, country from russlavbank.bnk_city ;";
		$cidadesComPaises = $db->getall($sql);
		$cidades = array();
		$paises = array();
		foreach ($cidadesComPaises as $cidade) {

			if (in_array($cidade->nome, $cidadesAInserir)) {
				array_push($cidades, $db->quote($cidade->nome));
				//643 - Russian Federation
				if ($cidade->country == 0) {
					$cidade->country = 643;
				}
				array_push($paises, $cidade->country);
			}
		}

		$values = '';

		for ($i = 0; $i < $tamanho; $i++) {
			$values = $values . '(' . $cidades[$i] . ',' . $paises[$i] . '),';
			/* if($i==5)
			 {break;} */
		}
		$values = substr($values, 0, -1);
		$sql = "
            insert into officeschema.ciudades
            (CiuCiudad,CiuPais)
            values $values;";

		/*echo $sql . '<br />';
		 return true;
		 die;*/
		return $db->query($sql);
	}

	public function verificaTabelaDePaises() {
		global $db;
		//var_dump($db);die;
		//Não verifica se há paises novos

		$sql = "select country from russlavbank.banks where rec_curr like '%EUR%' and deleted=0 group by country;";
		$origem = $db->getallsinglearray($sql);

		//Apaga todas as tarifas que existam para o correspondente, 306, RusslavBank
		$sql = 'delete  from officeschema.hd_detalletarifas where dtr_corresponsal=306;';
		$db->query($sql);

		foreach ($origem as &$pais) {
			//643 - Russian Federation
			if ($pais == 0) {
				$pais = 643;
			}
			//insere nas tarifas
			$sql = "INSERT INTO `officeschema`.`hd_detalletarifas` (`dtr_Corresponsal`, `dtr_Pais`, `dtr_MCobro`, `dtr_MPago`, `dtr_IDesde`, `dtr_IHasta`, `dtr_PCambio`, `dtr_PComision`, `dtr_PAgente`, `dtr_Fijo`, `dtr_FijoAgente`, `dtr_MinimoEmpresa`, `dtr_FijoUrgente`, `dtr_Usuario`, `dtr_PorcentAgn`, `dtr_Status`)
			VALUES (306, $pais, 1, 'EUR', 0, 0, 0, 0, 0, 0, 0, 0, 0, 601, 0, 5);";
			//echo $sql.'<br />';
			$db->query($sql);
			//Activa os paises
			$sql = "UPDATE `officeschema`.`hd_paises` SET `pai_ActivoGiros`=1 WHERE `pai_CodElite`=$pais;";
			//echo $sql.'<br />';
			$db->query($sql);
		}
		return true;
		/*
		 printArray($origem);

		 $sql = "select pai_codelite from officeschema.hd_paises WHERE pai_ActivoGiros = 1;";
		 $destino=$db->getallsinglearray($sql);
		 printArray($destino);

		 $a=$origem;
		 $b=$destino;
		 $c=array_unique(array_merge ($a,$b));
		 $c=array_diff($c,$b);
		 printArray($c);
		 //return true;

		 $origensAInserir=$c;
		 $tamanho=count($origensAInserir);
		 if($tamanho==0)
		 {
		 return true;
		 }

		 $sql="select id,name_lat as nome from russlavbank.country where russlavbank.country.ERASED=0 and rec_curr like '%EUR%';";
		 $destinos=$db->getall($sql);
		 $ids=array();
		 $nomes=array();
		 foreach ($destinos as $destino)
		 {
		 if(in_array($destino->nome,$origensAInserir))
		 {

		 if($destino->nome=='??????' ||$destino->id==492)
		 {
		 $tamanho--;
		 continue;
		 }
		 array_push($ids,$destino->id);
		 array_push($nomes,$db->quote($destino->nome));
		 }
		 }
		 if($tamanho==0)
		 {
		 return true;
		 }
		 $values='';
		 for($i=0;$i<$tamanho;$i++)
		 {

		 $values=$values.'('.$ids[$i].','.$nomes[$i].',1),';
		 }
		 $values = substr($values, 0, -1);
		 $sql = "
		 insert into officeschema.hd_paises
		 (pai_codelite,pai_nombreUSD,pai_activogiros)
		 values $values ON DUPLICATE KEY UPDATE pai_activogiros=1;";


		 return $db->query($sql); */
	}
	public function xml_getparse($contents, $get_attributes=1, $priority = 'tag') {
		if (!$contents)
		return array();
		if (!function_exists('xml_parser_create')) {
			return array();
		}
		$parser = xml_parser_create('');
		xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
		xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
		xml_parse_into_struct($parser, trim($contents), $xml_values);
		xml_parser_free($parser);
		if (!$xml_values)
		return;
		$xml_array = array();
		$parents = array();
		$opened_tags = array();
		$arr = array();
		$current = &$xml_array;
		$repeated_tag_index = array();
		foreach ($xml_values as $data) {
			unset($attributes, $value);
			extract($data);
			$result = array();
			$attributes_data = array();
			if (isset($value)) {
				if ($priority == 'tag')
				$result = $value;
				else
				$result['value'] = $value;
			}
			if (isset($attributes) && $get_attributes) {
				foreach ($attributes as $attr => $val) {
					if ($priority == 'tag')
					$attributes_data[$attr] = $val;
					else
					$result['attr'][$attr] = $val;
				}
			}
			if ($type == "open") {
				$parent[$level - 1] = &$current;
				if (!is_array($current) or (!in_array($tag, array_keys($current)))) {
					$current[$tag] = $result;
					if ($attributes_data)
					$current[$tag . '_attr'] = $attributes_data;
					$repeated_tag_index[$tag . '_' . $level] = 1;

					$current = &$current[$tag];
				} else {

					if (isset($current[$tag][0])) {
						$current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
						$repeated_tag_index[$tag . '_' . $level]++;
					} else {
						$current[$tag] = array($current[$tag], $result);
						$repeated_tag_index[$tag . '_' . $level] = 2;

						if (isset($current[$tag . '_attr'])) {
							$current[$tag]['0_attr'] = $current[$tag . '_attr'];
							unset($current[$tag . '_attr']);
						}
					}
					$last_item_index = $repeated_tag_index[$tag . '_' . $level] - 1;
					$current = &$current[$tag][$last_item_index];
				}
			} elseif ($type == "complete") {
				if (!isset($current[$tag])) {
					$current[$tag] = $result;
					$repeated_tag_index[$tag . '_' . $level] = 1;
					if ($priority == 'tag' && $attributes_data)
					$current[$tag . '_attr'] = $attributes_data;
				} else {
					if (isset($current[$tag][0]) && is_array($current[$tag])) {
						$current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;

						if ($priority == 'tag' && $get_attributes && $attributes_data) {
							$current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
						}
						$repeated_tag_index[$tag . '_' . $level]++;
					} else {
						$current[$tag] = array($current[$tag], $result);
						$repeated_tag_index[$tag . '_' . $level] = 1;
						if ($priority == 'tag' && $get_attributes) {
							if (isset($current[$tag . '_attr'])) {
								$current[$tag]['0_attr'] = $current[$tag . '_attr'];
								unset($current[$tag . '_attr']);
							}
							if ($attributes_data) {
								$current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
							}
						}
						$repeated_tag_index[$tag . '_' . $level]++;
					}
				}
			} elseif ($type == 'close') {
				$current = &$parent[$level - 1];
			}
		}
		return($xml_array);
	}
	public function objectsIntoArray($arrObjData, $arrSkipIndices = array()) {
		$arrData = array();
		// if input is object, convert into array
		if (is_object($arrObjData)) {
			$arrObjData = get_object_vars($arrObjData);
		}
		if (is_array($arrObjData)) {
			foreach ($arrObjData as $index => $value) {
				if (is_object($value) || is_array($value)) {
					$value = $this->objectsIntoArray($value, $arrSkipIndices); // recursive call
				}
				if (in_array($index, $arrSkipIndices)) {
					continue;
				}
				$arrData[$index] = $value;
			}
		}
		return $arrData;
	}


}

